/*
* Copyright (c) 2007 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#ifndef M_CGMATERIAL_H
#define M_CGMATERIAL_H

#include "material.h"
#include "cgheaders.h"
#include "cgstatemanager.h"

namespace Engine
{
	class CGMaterial;
	/**
	*   Implementation of rendering pass (render states and shaders)
	*/
	class CGPass: public Pass
	{
	public:
		CGPass(CGpass pass, CGMaterial* material):m_pass(pass),m_material(material){}

		~CGPass(){}

		/**
		*   Apply some render states.
		*/
		virtual void Begin() const;
		/**
		*   Restore device state.
		*/
		virtual void End() const;

	private:

		CGpass m_pass;
		CGMaterial* m_material;
	};

	/**
	*   Effect implementation for specific hardware level.
	*/
	class CGTechnique: public Technique
	{
	public:
		typedef std::vector<RefPtr<CGPass, WeakPtrExtension> > PassVector;

		CGTechnique(const std::string& name, CGtechnique technique, CGMaterial* material);

		~CGTechnique();

		/**
		*   Return pass count.
		*/
		virtual unsigned int GetPassCount() const;

		/**
		*   Return pass for this technique.
		*/
		virtual const PassPtr GetPass(unsigned int index) const;

	private:

		CGtechnique m_technique;
		PassVector m_passes;
	};


	/**
	*   Implement visual properties of objects definition.
	*/
	class CGMaterial: public Material
	{
	public:
		typedef std::map<std::string, TexturePtr> TexturesMap;

		CGMaterial(const std::string& name);

		virtual ~CGMaterial();

		/**
		*   Return true if material has alpha blend operations.
		*/
		virtual bool IsTransparent()const;

		/**
		*   Return technique bass much current hardware.
		*/
		virtual const TechniquePtr GetBestTechnique() const;

		/**
		*   Load material.
		*/
		virtual void Load();

		/**
		*   UnLoad material.
		*/
		virtual void UnLoad();

		/**
		*   Get texture assigned to this material
		*/
		TexturePtr GetTexture(const std::string& name);

	private:

		CGeffect m_effect;
		RefPtr<CGTechnique,WeakPtrExtension> m_bestTechnique;
		bool m_isTransparent;
		TexturesMap m_textures;

	};

	/**
	*   Factory for creating material resources.
	*/
	class CGMaterialFactory: public MaterialFactory
	{
	public:
		CGMaterialFactory();

		/**
		*   Returns the factory type.
		*/
		virtual const std::string& GetType() const {return m_type;}

		/**
		*   Creates a new object.
		*   @param name Name of the object to create
		*   @return	An object created by the factory. The type of the object depends on	the factory.
		*/
		virtual CGMaterial* CreateInstance( const std::string& name );

	private:

		std::string m_type;
		RefPtr<CGStateManager> m_stateManager;
	};
}

#endif
